import xlsx, { WorkBook, Range, WritingOptions } from "xlsx";
/**
 * 导出单 sheet excel 文件
 * @param array 数组
 * @param filePath 文件路径
 * @param mergeRange 合并单元格范围
 */
export async function exportExcelFromAoa(
  array: (string | number)[][],
  filePath = "example.xs",
  mergeRange?: Range[],
  cellWidthList: number[] = []
): Promise<{ type: "success" | "error"; message?: string }> {
  const sheetName = "sheet1";
  const worksheet = xlsx.utils.aoa_to_sheet(array);

  /** 自适应列宽 */
  const columnWidths: { wch: number }[] = [];
  const header = array[0]; // 行头
  for (let i = 0; i < header.length; i++) {
    // 处理列
    const columnName = header[i];
    let maxLength = String(columnName).length;
    for (let j = 0; j < array.length; j++) {
      // 处理行
      const cell = worksheet[xlsx.utils.encode_cell({ r: j, c: i })];
      if (cell) {
        const cellValue = cell.v.toString();
        if (cellValue.length > maxLength) {
          maxLength = cellValue.length;
        }
      }
    }
    const adjustedWidth = Math.ceil((maxLength + 8) * 1.2); // 加上一些额外宽度
    columnWidths.push({ wch: cellWidthList[i] || adjustedWidth });
  }
  worksheet["!cols"] = columnWidths;

  if (mergeRange?.length) {
    worksheet["!merges"] = mergeRange;
  }

  const workBook: WorkBook = {
    SheetNames: [sheetName],
    Sheets: {
      [sheetName]: worksheet
    }
  };

  const options: WritingOptions = {
    type: "file" // 输出类型，可以是 'file' 或 'buffer'
  };
  const res = await new Promise<{ type: "success" | "error"; message?: string }>((resolve, reject) => {
    xlsx.writeFileAsync(filePath, workBook, options, (error?: any) => {
      if (!error) {
        app.$notify({
          title: "导出成功",
          type: "success",
          message: ""
        });
        resolve({ type: "success" });
      } else {
        let msg = error && error.message;
        if (/no such file or directory/g.test(msg)) {
          msg = "导出路径有误，请重新设置导出路径。";
        } else if (/resource busy or locked/g.test(msg)) {
          msg = "文件已在本地打开，无法替换，请将本地文件关闭后再导出。";
        }
        app.$notify({
          title: "导出失败",
          type: "info",
          message: msg
        });
        console.error(error);
        reject({ type: "error", message: msg });
      }
    });
  });
  return res;
}
